package bsk_dac.users;

import bsk_dac.DACPanel;
import bsk_dac.MainDACFrame;
import bsk_dac.PrivilegesPanel;
import bsk_dac.actions.SelectingUser;
import bsk_dac.UserPanel;
import bsk_dac.accesscontrol.TableAccess;
import bsk_dac.accesscontrol.AccessType;
import bsk_dac.tables.TablesManager;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;

/**
 * Narazie największa krowa w całym projekcie.
 */
public class UsersManager implements IUsersManager {

    private DACPanel dacPanel;
    private Map<User, ArrayList<PrivilegesPanel>> usersRow;
    private ArrayList<PrivilegesPanel> privilegesPanelRow;
    private User selectedUser;
    private TablesManager tablesManager = TablesManager.getTableManager();

    public UsersManager(DACPanel dacPanel) {
        this.dacPanel = dacPanel;
        loadUsers();
    }

    public void setSelectedUser(User selectedUser) {
        this.selectedUser = selectedUser;
    }

    public User getSelectedUser() {
        return selectedUser;
    }

    public User getUser(String userName){
        ArrayList<User> users =  new ArrayList<User>(usersRow.keySet());
        for(User user : users){
            if(user.getUserName().equals(userName)){
                return user;
            }
        }
        return null;
    }

    public int getUsersCount() {
        if (usersRow != null) {
            return usersRow.size();
        }
        return 0;
    }

    public ArrayList<User> getUsersList() {
        return new ArrayList<User>(usersRow.keySet());
    }

    public void loadUsers() {
        usersRow = new HashMap<User, ArrayList<PrivilegesPanel>>();
        privilegesPanelRow = new ArrayList<PrivilegesPanel>();
        ArrayList<User> fetchedUsers = getUsersFromDatabase();
        createPanelsForUsers(fetchedUsers);
    }

    private ArrayList<User> getUsersFromDatabase() {
        //Pobranie użytkowników z bazy danych
        //narazie jest tutaj mała atrapa i użytkonicy są wpisywanie ręcznie
        ArrayList<User> fetchedUsers = new ArrayList<User>();
        createNewUsersBasedOnFetchedFromDatabase(fetchedUsers);
        loadUsersAccessDataFromDatabase(fetchedUsers);

        return fetchedUsers;
    }

    private void createNewUsersBasedOnFetchedFromDatabase(ArrayList<User> fetchedUsers) {
        try {
            Connection conn = MainDACFrame.conn;
            Statement stmt = null;
            String query = "select login FROM users";
            stmt = (Statement) conn.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
                String userName = rs.getString("login");
                fetchedUsers.add(new User(userName));
            }
        } catch (SQLException ex) {
            Logger.getLogger(UsersManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void loadUsersAccessDataFromDatabase(ArrayList<User> fetchedUsers) {
        if (fetchedUsers != null) {
            for (User user : fetchedUsers) {
                user.loadAccessFromDatabase();
            }

        }
    }

    /**
     * Dodaje kompletne wiersze z nazwą i uprawnieniami dla każdego użytkownika
     * @param users
     */
    private void createPanelsForUsers(ArrayList<User> users) {
        for (User user : users) {
            createPrivilegesPanelRowForSingleUser(user);
        }
    }

    /**
     * Tworzy jeden wiersz z prawami dostępu dla użytkownika
     * Kolumnami w tym wierszu są pojedyńcze tabele.
     *
     * @param user
     */
    private void createPrivilegesPanelRowForSingleUser(User user) {
        privilegesPanelRow.clear();
        dacPanel.addUserPanel(user);

        for (String tableName : tablesManager.getAvaiableTables()) {
            dacPanel.addPrivilegesPanel(tableName, user);
        }
        usersRow.put(user, privilegesPanelRow);
    }
}
